/*
 * anima/mm.hh - Generic memory management interface.
 * Copyright (C) 2007  Mikhail Vorozhtsov
 * See the LICENSE section of the README file for details.
 */

/* $Id$ */

#ifndef HEADER_ANIMA_MM_HH
#define HEADER_ANIMA_MM_HH

#include ANIMA_ARCH_HEADER (mm.hh)
#include HEADER (anima,object.hh)

START_NAMESPACE (anima)

class mm : public ANIMA_ARCH::mm
{
private:
  static bool _initialized_p;

public:
  static bool init ();
  static bool init_cpu ();

public:
  INLINE
  static bool
  initialized_p ()
  {
    return _initialized_p;
  }

public:
  static void install (space_t *space);

public:
  static void *map (ct_t ct = CT_COMMON);
  static void *map (u64_t paddr, tte_t::flag_t flags = tte_t::FLAG_DEFAULTS);
  static void unmap (u64_t addr);

private:
  static object_t::state_t use (object_t *obj, ct_t ct, u64_t serial,
                                object_t::state_t state);
  static bool unmap (object_t *obj, ct_t ct, u64_t serial);

public:

#define __ANIMA_MM_USE(PREFIX,CT) \
  INLINE \
  static object_t::state_t \
  use (PREFIX ## _t *obj, object_t::state_t state) \
  { \
    return use ((object_t *) obj, CT, object_t::SERIAL_NONE, state); \
  } \
  \
  INLINE \
  static object_t::state_t \
  use (PREFIX ## _ref_t ref, object_t::state_t state) \
  { \
    return use ((object_t *) ref.get (), CT, ref.serial, state); \
  } \
  \
  INLINE \
  static bool \
  unmap (PREFIX ## _ref_t ref) \
  { \
    return unmap ((object_t *) ref.get (), CT, ref.serial); \
  }

  __ANIMA_MM_USE (cpu, CT_CPU)
  __ANIMA_MM_USE (space, CT_SPACE)
  __ANIMA_MM_USE (thread, CT_THREAD)

#undef __ANIMA_MM_USE

  static void activate (object_t *obj);
  static object_t::state_t change_state (object_t *obj,
                                         object_t::state_t state);
  static void unuse (object_t *obj);

public:
  static u64_t length (u64_t paddr);
  static bool cp (u64_t paddr, void *dst, u64_t size);
  static bool cp (const void *src, u64_t paddr, u64_t size);
};

END_NAMESPACE

#endif /* HEADER_ANIMA_MM_HH */

